#ifndef __ROSBAG_RECORD_NODE_H__
#define __ROSBAG_RECORD_NODE_H__

#include <ros/ros.h>
#include <ros/package.h>
#include <nav_msgs/MapMetaData.h>
#include <nav_msgs/OccupancyGrid.h>
#include <nav_msgs/Path.h>
#include <std_msgs/String.h>
#include <sensor_msgs/LaserScan.h>
#include <sensor_msgs/Imu.h>
#include <nav_msgs/Odometry.h>
#include <tf2_msgs/TFMessage.h>

#include <iostream>
#include <sstream>
#include <thread>
#include <unordered_map>
#include <bags_record/bag_file.h>
using namespace std;

// Bag内部话题结构
struct BagTopic{
    string topic_name;      //话题名称
    string data_format;     //消息数据格式
    bool disable = false;   //是否禁用 默认不禁用
    double save_hz = -1.0;
    double time_interval = -1.0; 
    double max_time_limit = 600.0;  //10 min
    std::deque<rosbag::MessageInstance> message_deque;     //消息存储队列
};

// 事件类型
enum class EventType{
    UNKNOWN = 0,
    TRIGGER,      //话题订阅
    SERVER,     //服务触发
};


// 事件触发机制
struct BagSaveEvent{
    EventType event_type = EventType::UNKNOWN;      //保存类型
    string file_name = "";                          //保存文件名称
    ros::Time bag_start_time = ros::Time(0);        //开始保存时间
    ros::Time trigger_time = ros::Time(0);          //触发时间
    ros::Time save_time = ros::Time(0);             //延迟保存时间
    string node_name = "";                          //节点名称
    int error_code = 0;                             //错误码  
    string description = "";                        //简要描述词 EventType::SERVER
};

class BagsRecord{
    public:
        BagsRecord();
        ~BagsRecord();

        // 参数初始化
        void initParams();

        // 初始化订阅者
        void SubscriberInit();   
        // 处理雷达类型消息
        void HandleLaserScanMessage(BagTopic bag_topic, const sensor_msgs::LaserScan::ConstPtr& msg);
        // 处理地图类型消息
        void HandleOccupancyGridMessage(BagTopic bag_topic, const nav_msgs::OccupancyGrid::ConstPtr& msg);
        // 处理Path类型消息
        void HandlePathMessage(BagTopic bag_topic, const nav_msgs::Path::ConstPtr& msg);
        // 处理String类型消息
        void HandleStringMessage(BagTopic bag_topic, const std_msgs::String::ConstPtr& msg);
        // 处理Imu类型消息
        void HandleImuMessage(BagTopic bag_topic, const sensor_msgs::Imu::ConstPtr& msg);
        // 处理Odometry类型消息
        void HandleOdometryMessage(BagTopic bag_topic, const nav_msgs::Odometry::ConstPtr& msg);
        // 处理TFMessage类型消息
        void HandleTFMessageMessage(BagTopic bag_topic, const tf2_msgs::TFMessage::ConstPtr& msg);

    private:
        ros::NodeHandle __nh;
        BagFile bagFile_;
        string configFilePath_;
        string bagsDir_;
        vector<BagTopic> bagTopicsVec_;
        std::unordered_map<string, ros::Subscriber> subList_;
        float __bags_data_save_time, __bags_delay_save_time;
};

#endif